/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package descriptor;

import javax.sql.DataSource;
import database.DatabaseConnection;
import exceptions.DatabaseException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;

/**
 *
 * @author Alejandro
 */
public class EntityDAO {

    private DataSource ds;
    private Application app;
    private String source;

    public EntityDAO() {
        app = Application.getInstance();
        source = "";
        DatabaseConnection dbc = DatabaseConnection.getInstance();
        ds = dbc.getDataSource();
    }

    public EntityDAO(String source) {
        this();
        this.source = source;
    }

    public void bind(String source) {
        this.source = source;
    }

    public EntityPresentation findByPrimaryKey(String primaryKey) throws DatabaseException {
        try {
            Template template = app.getTemplate(source);
            Connection c = ds.getConnection();

            String stWhere = "";
            String stFrom = "FROM " + template.getTableName() + " ";
            StringBuilder stSelect = new StringBuilder();
            stSelect.append("SELECT ");
            Iterator<PropertyTemplate> it = template.getPropertyTemplateCollection().iterator();
            while (it.hasNext()) {
                PropertyTemplate pt = it.next();
                stSelect.append(pt.getName());
                if (it.hasNext()) {
                    stSelect.append(", ");
                } else {
                    stSelect.append(" ");
                }
                if (pt.isPrimaryKey()) {
                    stWhere = "WHERE " + pt.getName() + "=" + primaryKey;
                }
            }
            PreparedStatement st = c.prepareStatement(stSelect.toString() + stFrom + stWhere);
            ResultSet rs = st.executeQuery();
            if (rs.next()) {
                Entity e = new Entity(source);
                e.parse(new SqlParser(rs));
                st.close();
                c.close();
                return e;
            } else {
                st.close();
                c.close();
                return null;
            }
        } catch (SQLException ex) {
            throw new DatabaseException(ex);
        } catch (NullPointerException ex) {
            throw new DatabaseException(ex);
        }
    }

    public Iterable<EntityPresentation> findAll() throws DatabaseException {
        try {
            Collection<EntityPresentation> container = new LinkedList<EntityPresentation>();
            Template template = app.getTemplate(source);
            Connection c = ds.getConnection();
            String stFrom = "FROM " + template.getTableName();
            StringBuilder stSelect = new StringBuilder();
            stSelect.append("SELECT ");
            Iterator<PropertyTemplate> it = template.getPropertyTemplateCollection().iterator();
            while (it.hasNext()) {
                PropertyTemplate pt = it.next();
                stSelect.append(pt.getName());
                if (it.hasNext()) {
                    stSelect.append(", ");
                } else {
                    stSelect.append(" ");
                }
            }
            PreparedStatement st = c.prepareStatement(stSelect.toString() + stFrom);
            ResultSet rs = st.executeQuery();
            while (rs.next()) {
                Entity e = new Entity(source);
                e.parse(new SqlParser(rs));
                container.add(e);
            }
            st.close();
            c.close();
            return container;
        } catch (SQLException ex) {
            throw new DatabaseException(ex);
        } catch (NullPointerException ex) {
            throw new DatabaseException(ex);
        }
    }
}
